package org.vectrics.recruiter.struts.admin.employee;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;
import org.apache.struts.config.ActionConfig;
import org.vectrics.domain.Domain;
import org.vectrics.employee.Employee;
import org.vectrics.location.Location;
import org.vectrics.provider.CoreServiceLocator;
import org.vectrics.recruiter.RecruitServiceLocator;
import org.vectrics.recruiter.job.JobFunction;
import org.vectrics.recruiter.struts.admin.PersonSearchAction;
import org.vectrics.recruiter.struts.admin.UserSearchForm;
import org.vectrics.struts.HttpRequestConverter;
import org.vectrics.struts.Request;
import org.vectrics.user.EmployeePersonSearchCriteria;
import org.vectrics.user.Person;
import org.vectrics.user.PersonSearchCriteria;

import com.hexacta.hrs.securitygroups.Permission;
import com.hexacta.hrs.securitygroups.PermissionName;
import com.hexacta.hrs.securitygroups.PermissionNameConverter;
import com.hexacta.hrs.securitygroups.SecurityGroup;
import com.hexacta.hrs.web.struts.actions.security.PermissionChecker;

/**
 * @author pgoette Clase encargada de settear los criterios que se van a ver
 *         reflejados en las busquedas
 */

public class EmployeeSearchAction extends PersonSearchAction {

    private transient static Logger log = Logger.getLogger(EmployeeSearchAction.class);

    private Map<String, Object> session;

    private PermissionChecker permissionChecker = new PermissionChecker();

    private PermissionNameConverter permissionNameConverter = new PermissionNameConverter();

    /**
     * @see PersonSearchAction#SetearCriterio(UserSearchForm,
     *      HttpServletRequest)
     */
    @Override
    protected void SetearCriterio(final UserSearchForm form, final HttpServletRequest request) {

        // Creo el criterio.
        setCriteria(new EmployeePersonSearchCriteria(CoreServiceLocator.createPersonSearchCriteria()));

        super.SetearCriterio(form, request);

        getCriteria().setEmployeesOnly(true);
        EmployeePersonSearchCriteria criterio = (EmployeePersonSearchCriteria) getCriteria();

        // Se setean los datos propios del empleado a buscar

        // Si la location no es nula ni vacia busco la location y la agrego al
        // criterio.
        EmployeeSearchForm formEmployee = (EmployeeSearchForm) form;

        if (formEmployee.getOfficeLocation() != null && !formEmployee.getOfficeLocation().equals("")) {
            Location location = RecruitServiceLocator.getLocationService().findLocation(
                    new Long(formEmployee.getOfficeLocation()));
            criterio.addOfficeLocation(location);
        }

        if (formEmployee.getFunction() != null && !formEmployee.getFunction().equals("")) {
            JobFunction jobFunction = RecruitServiceLocator.getJobProvider().findFunction(formEmployee.getFunction());
            criterio.setFunction(jobFunction);
        }

        Request vectricsRequest = HttpRequestConverter.convertRequest(request);
        Domain domain = CoreServiceLocator.getUserAuthService().getSessionDomain(vectricsRequest);

        Person person = CoreServiceLocator.getUserAuthService().getAuthorizedPerson(domain, vectricsRequest);

        if (!hasPermission(PermissionName.VIEW_ALL_EMPLOYEES.toString(), person)) {
            Employee loggedUssr = CoreServiceLocator.getEmployeeService().searchByPerson(person);

            criterio.setLoggedPersonFunction(loggedUssr.getFunction());
        }
        criterio.setLoggedPersonCanViewInactive(hasPermission(PermissionName.VIEW_INACTIVE_EMPLOYEES.toString(), person));
        criterio.setActive(formEmployee.getActive().equalsIgnoreCase("true"));

        HttpSession session = request.getSession();
        session.setAttribute("userSelectCriteria", criterio);
    }

    @Override
    protected boolean isChangePage(final HttpServletRequest request, final UserSearchForm form) {
        // Pregunto si fue un cambio de pagina a PersonSearchAction
        boolean resultado = super.isChangePage(request, form);
        // Si fue un cambio de pagina
        if (resultado) {
            // Seteo la office Location al formulario
            EmployeeSearchForm employeeForm = (EmployeeSearchForm) form;
            EmployeePersonSearchCriteria employeeCriteria = (EmployeePersonSearchCriteria) getCriteria();
            if (employeeCriteria.getOfficeLocations() != null && employeeCriteria.getOfficeLocations().size() > 0) {
                Location officeLocation = employeeCriteria.getOfficeLocations().iterator().next();
                employeeForm.setOfficeLocation(officeLocation.getName());
                request.setAttribute("officeLocation", officeLocation.getId().toString());
            }

            if (employeeCriteria.getFunction() != null) {
                JobFunction jobFunction = employeeCriteria.getFunction();
                employeeForm.setFunction(jobFunction.getCode());
                request.setAttribute("function", jobFunction.getCode());
            }
        }

        return resultado;
    }

    @Override
    protected UserSearchForm getNewForm() {
        return new EmployeeSearchForm();
    }

    @Override
    protected PersonSearchCriteria getNewCriterial() {
        return new EmployeePersonSearchCriteria(CoreServiceLocator.createPersonSearchCriteria());
    }

    @Override
    protected boolean isResetPage(final HttpServletRequest request, final ActionConfig mapping) {
        boolean resultado = super.isResetPage(request, mapping);
        if (resultado) {
            request.setAttribute("function", "");
            request.removeAttribute("funtion");

            EmployeeSearchForm form = (EmployeeSearchForm) request.getAttribute(mapping.getAttribute());
            form.setFunction(null);

        }
        return resultado;
    }

    public boolean hasPermission(final String permission, final Person user) {
        for (SecurityGroup group : user.getUser().getSecurityGroups()) {
            for (Permission rol : group.getSecurityGroupRoles()) {
                if (rol.getName().toString().equalsIgnoreCase(permission))
                    return true;
            }
        }
        return false;
    }

    /**
     * @param permissionChecker
     *            the permissionChecker to set
     */
    public void setPermissionChecker(final PermissionChecker permissionChecker) {
        this.permissionChecker = permissionChecker;
    }

    /**
     * @param permissionNameConverter
     *            the permissionNameConverter to set
     */
    public void setPermissionNameConverter(final PermissionNameConverter permissionNameConverter) {
        this.permissionNameConverter = permissionNameConverter;
    }

    /**
     * @return the permissionChecker
     */
    public PermissionChecker getPermissionChecker() {
        return permissionChecker;
    }

    /**
     * @return the permissionNameConverter
     */
    public PermissionNameConverter getPermissionNameConverter() {
        return permissionNameConverter;
    }

}
